import numpy as np

# a = np.array([1,2,3]) # 从python列表创建一维矩阵
# print(a)

# b = np.array([1,2,3],dtype=np.int32) # 指定数据类型为np.int32
# print(b)

# c = np.array([[1,2,3],[4,5,6]]) # 从python列表创建二维矩阵，2行3列
# print(c)
# print(c.shape)

# d = np.zeros((3,4))
# print(d)

# e = np.ones((3,4),dtype=np.int64)
# print(e)

# f = np.arange(10)
# print(f)

# g = np.arange(10,20,2) #10-19的数据，2步长
# print(g)

# h = np.linspace(1,10,5) # 区间为[1,10],取5个点
# print(h)
# print(h.dtype)

# np.random.seed(0)
# print(dir(np.random))
# print(help(np.random))

# r = np.random.rand() # 生成[0,1)区间的float类型随机数
# print(r)

# r1 = np.random.rand(2,3) # 生成2行3列的随机浮点数二维数组，注意参数的写法
# print(r1)

# r2 = np.random.random((2,3)) # 生成2行3列的随机浮点数二维数组，注意参数的写法
# print(r2)

# r3 = np.random.randn(2,3) # 生成2行3列的随机浮点数二维数组，注意元素值的发布
# print(r3)

# r5 = np.random.normal(10,3.5,size=(2,3)) # 生成2行3列的二维数组，注意元素值的分布
# print(r5)


# ra = np.random.randint(13) # 生成一个值在[0,13)区间的随机整数
# print(ra)

# ra1 = np.random.randint(2,13) # 生成一个值在[2,13)区间的随机整数
# print(ra1)

# ra2 = np.random.randint(10,size=10) # 生成一个含有10个元素值在区间[0,10)区间的以为数组
# print(ra2)

# ra3 = np.random.randint(10,size=(2,3)) #生成2行3列的随机整数二维数组
# print(ra3)

# a = np.arange(12)
# print(a)
# print(a.shape)

# b = np.reshape(a,(3,4))
# print(b)

# c = b.reshape(2,1,6)
# print(c)

# d = b.reshape(2,1,2,3)
# print(d)

# a = np.array([1,2,3]) # a 是 shape 为（3,)的一维数组
# print(a)

# b = np.tile(a,(4)) # 所有元素重复4次，得到shape为（12,）的一维数组
# print(b)

# c = np.tile(a,(4,1)) # 每行重复4次得到shape为 (4,3) 的二维数组
# print(c)

# d = np.tile(a,(4,2)) # 每行重复4次，每列重复2次，得到shape为(4,6)的二维新数组
# print(d)

# e = np.tile(a,(4,2,1)) # 在三个维度上重复4、2、1,新数组shape为(4,2,3)
# print(e)

# a = np.array([20,30,40,50])
# b_array = np.array([0,1,2,3])
# c = a - b_array # 对应元素相减，生成新对象
# print(c)

# d = b_array ** 2 # 每个元素平方，生成新对象
# print(d)

# e = 10 * np.sin(a) # 每个元素取正弦后乘以10，生成新对象
# print(e)

# f = a < 35 # 每个元素小于35的布尔值，生成新对象
# print(f)

# A = np.array([[1,1],[0,1]])
# print(A)

# B = np.array([[2,0],[3,4]])
# print(B)

# AB = A * B
# print(AB)

# AB_matmul = A @ B #矩阵相乘
# print(AB_matmul)

# AB_dot = A.dot(B)
# print(AB_dot)

# a = np.array([[0,0,0],[10,10,10]])
# print(a)

# b = np.array([1,2,3])
# print(b)

# broadcast = a + b  # 自动触发广播机制，相当于 b 变为含有 2 行相同元素的二维数组
# print(broadcast)

# b = np.arange(12).reshape(3,4)
# print(b)

# print(b.sum(axis=0)) # 得到每列的求和

# print(b.min(axis=1)) # 得到每行的最小值

# print(b.cumsum(axis=1)) # 每行进行累加

# b = np.arange(24).reshape(2,3,4) # 构建三维数组
# print(b)

# print(b.sum(axis=0)) # 按第1个维度求和，该维度上有2个元素进行求和，结果对象shape为(3,4)

# a = np.arange(12).reshape(3,4)
# print(a)

# print(np.argmin(a)) # 最小值的全局索引为0

# print(np.argmax(a)) # 最大值的全局索引为11

# print(np.argmin(a,axis=1)) # 每行最小值的行索引

# print(np.argmin(a,axis=0)) # 每列最小值的列索引

# a = np.arange(12,0,-1).reshape(3,4)
# print(a)

# print(np.sort(a)) # 默认按行排序 

# print(np.sort(a,axis=1)) # 按行排序

# print(np.sort(a,axis=0)) # 按列排序

# a = np.arange(12,0,-1).reshape(3,4)
# print(a)

# print(a.T)

# b = np.arange(24,0,-1).reshape(2,3,4)
# print(b.T) # shape由原来的(2,3,4)变为(4,3,2)

# a = np.arange(10)
# print(a)

# print(a[2])

# print(a[1:5])

# b = np.arange(12).reshape(3,4)
# print(b)

# print(b[2][2]) # 第一种索引方法

# print(b[2,2]) # 第二种索引方法

# print(b[[0,0,1,1],[0,1,2,3]]) # 第三种索引方法 取(0,0),(0,1),(1,2),(1,3)四个位置的元素

# 一维数组切片
# a = np.array([2,3,4,5,6,1])
# print(a[2:6:2]) # 设置步长为2

# #多维组合切片
# b = np.arange(12).reshape(3,4)
# print(b[0:2, 0:2]) # 先取两行，再取两列。注意不同于b[0:2][0:2]

# print(b[0:2]) # 如果提供的索引少于数组的维度数，那么缺少的索引将被视为完整切片

# print(b[0:2, :]) # 与b[0:2]等价

# print(b[:-1, -1::-1]) #类似于Python中的切片，参数可以为负值或省略

# a = np.arange(6).reshape(2,3)
# print(a)

# print(a[:,[True,False,True]]) #去列表中对应列索引为False的列即第二列被删掉

# print(a[:,a[1] > 3]) # 第二行只有第2列和第3列的值大于3，对应的列被保留，第一列被删除

# print(a[[1,0,1],:]) #按列表中的行索引对数组调整，得到shape为(3,3)的数组

# print(a[:,[1,0,1,0,2]]) # 按列表中的列索引顺序对数组调整，得到shape为(2,5)的数组


# a = np.arange(12).reshape(2,3,2) # 三维数组，shape为(2,3,2)
# print(a)
# b = np.arange(6).reshape(1,3,2) # 三维数组，shape为(1,3,2)
# print(b)
# print(np.vstack((a,b))) # shape变为(3,3,2)

# a = np.array([1,2,3])
# print(a)

# b = np.array([4,5,6])
# print(b)

# print(np.hstack((a,b))) # 一维数组的横向合并

# c = np.array([[1,1,1],[1,1,1]])
# print(c)

# d = np.array([[2,2,2],[2,2,2]])
# print(d)

# print(np.hstack((c,d))) # 二维数组的横向合并，除第二个维度外，其他维度值应保持一致

# a = np.array([[1,1,1],[2,2,2]]) # shape为(2,3)
# print(a)
# b = np.array([[3,3,3],[4,4,4]])  # shape为(2,3)
# print(b)
# c = np.array([[5,5,5],[6,6,6]])  # shape为(2,3)
# print(c)

# print(np.concatenate((a,b,c),axis=0)) # 相当于np.vstack(a,b,c)，新数组shape为(6,3)

# print(np.concatenate((a,b,c),axis=1)) # 相当于np.hstack(a,b,c)，新数组shape为(2,9)

# a = np.arange(24).reshape((4,6))
# print(a)

# b = np.split(a,2,axis=0) #横向分割成2份，结果为list类型，长度为2
# print(b)
# print(b[0])

# c = np.split(a,3,axis=1) # 纵向分割成3份，结果为list类型，长度为3
# print(c)
# print(c[2])

# a = np.arange(12)
# print(a)

# b = a # 没有新对象生成，b相当于a的别名
# print(b)

# print(b is a) # a和b是同一个ndarray对象的两个名字而已

# b.shape = 3,4
# print(b)
# print(a)
# print(a.shape)

# a = np.arange(12).reshape(3,4)
# print(a)
# c = a.view()
# print(c) # c是一个新对象，而非a的别名

# print(c is a)

# print(c.base is a) # c是a对象数据的一个视图对象

# print(c.flags.owndata) # c的数据来自于a对象，而非自己

# c.shape = 2,6 # c的shape改变并不会影响a
# print(c)
# print(a)
# print(a.shape)

# c[0,4] = 1234 # 通过c修改数据会影响a
# print(a)
a = np.arange(12).reshape(3,4)
print(a)

d = a.copy() # d是一个新数组，数据来源于a数组
print(d)

print(d is a) # d不再与a有任何共享信息

print(d.base is a)

print(d.base is None) # d和a数据不共享

d[0,0] = 9999 # d的变化不会影响a
print(a)

# 有时如果不再需要原始数组，则应该在切片后调用copy()
# 假设a是一个很大的中间结果
# 最终结果b只包含a的一部分
# 那在用切片构造b时应该做一个深拷贝
# 删除a,从而释放内存
a = np.arange(int(1e8)) # a数组有10000000个元素
print(a)

b = a[:100].copy() # b复制了a的前100个元素，进行了深拷贝
print(b)

del a # a数组被释放






